From: robertl Date: Thu, 29 Apr 2010 02:16:09 +0000 (+0000) Subject: From Martin. X-Git-Tag: archive/raspbian/1.10.0+ds-2+rpi1~1^2~199^2~3 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=cbcbf1e3e9e77d6a201b175d5e286edf2d37c820;p=gpsbabel.git From Martin. --- diff --git a/garmin.c b/garmin.c index 1aeadfd16..fd01b6f2a 100644 --- a/garmin.c +++ b/garmin.c @@ -1070,6 +1070,7 @@ track_waypt_pr(const waypoint *wpt) strncpy((*cur_tx_tracklist_entry)->trk_ident, wpt->shortname, sizeof((*cur_tx_tracklist_entry)->trk_ident)); (*cur_tx_tracklist_entry)->trk_ident[sizeof((*cur_tx_tracklist_entry)->trk_ident)-1] = 0; } + (*cur_tx_tracklist_entry)->tnew = wpt->wpt_flags.new_trkseg; cur_tx_tracklist_entry++; } @@ -1077,7 +1078,7 @@ static int track_prepare(void) { int i; - int n = track_waypt_count() + track_count(); + int32 n = track_waypt_count() + track_count(); tx_tracklist = xcalloc(n, sizeof(GPS_PTrack)); cur_tx_tracklist_entry = tx_tracklist; @@ -1087,6 +1088,8 @@ track_prepare(void) my_track_count = 0; track_disp_all(track_hdr_pr, route_noop, track_waypt_pr); + GPS_Prepare_Track_For_Device(&tx_tracklist, &n); + return n; } diff --git a/jeeps/gps.h b/jeeps/gps.h index f09007908..ed9d2dacb 100644 --- a/jeeps/gps.h +++ b/jeeps/gps.h @@ -249,6 +249,14 @@ typedef struct GPS_SCourse_Point * sprint = 15 */ } GPS_OCourse_Point, *GPS_PCourse_Point; +typedef struct GPS_SCourse_Limits +{ + uint32 max_courses; + uint32 max_course_laps; + uint32 max_course_pnt; + uint32 max_course_trk_pnt; +} GPS_OCourse_Limits, *GPS_PCourse_Limits; + typedef int (*pcb_fn) (int, struct GPS_SWay **); diff --git a/jeeps/gpsapp.c b/jeeps/gpsapp.c index 81dc8e1c3..d84066747 100644 --- a/jeeps/gpsapp.c +++ b/jeeps/gpsapp.c @@ -3688,7 +3688,7 @@ int32 GPS_A301_Get(const char *port, GPS_PTrack **trk, pcb_fn cb, int protoid) if(!GPS_Device_On(port, &fd)) return gps_errno; - if ((trk_type == pD304) && gps_run_transfer != -1) { + if (protoid == 301 && trk_type == pD304 && gps_run_transfer != -1) { drain_run_cmd(fd); } @@ -3931,7 +3931,7 @@ int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n, int protoid, UC data[GPS_ARB_LEN]; GPS_PPacket tra; GPS_PPacket rec; - int32 i, j; + int32 i; int32 len; US method; US Pid_Trk_Data, Pid_Trk_Hdr, Cmnd_Transfer_Trk; @@ -3969,42 +3969,6 @@ int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n, int protoid, return GPS_UNSUPPORTED; } - /* D303/304 marks track segments with two consecutive invalid track - * points. Create them unless we're at the beginning of a track or there - * are already invalid track points (because the track was downloaded - * using D303/304). This needs to be done here because it will change - * the number of track points. - */ - if (trk_type == pD303 || trk_type == pD304) - { - for(i=0;itnew && i>0 && !trk[i]->ishdr && !trk[i-1]->ishdr) - { - /* Create in reverse order to avoid having to readjust the - * index after inserting the first point. - */ - for (j=i; j>=i-1; j--) - { - if (!Is_Trackpoint_Invalid(trk[j])) - { - GPS_PTrack trkpt = GPS_Track_New(); - *trkpt = *(trk[j]); - trkpt->no_latlon = 1; - trkpt->alt = 1e25; - trkpt->distance_populated = 0; - trkpt->heartrate = 0; - trkpt->cadence = 0xff; - trk = xrealloc(trk, (n+1) * sizeof(GPS_PTrack)); - memmove(&trk[i+1], &trk[i], (n-i) * sizeof(GPS_PTrack)); - n++; - trk[i] = trkpt; - } - } - } - } - } - if(protoid != 302 && !GPS_Device_On(port, &fd)) return gps_errno; @@ -7188,6 +7152,89 @@ void GPS_D1012_Send(UC *data, GPS_PCourse_Point cpt, int32 *len) } +/* @func GPS_A1009_Get ****************************************************** +** +** Get course limits from GPS +** +** @param [r] port [const char *] serial port +** @param [w] limits [GPS_PCourse_Limits] course limits structure +** +** @return [int32] success +************************************************************************/ + +int32 GPS_A1009_Get(const char *port, GPS_PCourse_Limits limits) +{ + static UC data[2]; + gpsdevh *fd; + GPS_PPacket trapkt; + GPS_PPacket recpkt; + + if (gps_course_limits_transfer == -1) + return GPS_UNSUPPORTED; + + if (!GPS_Device_On(port, &fd)) + return gps_errno; + + if (!(trapkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) + return MEMORY_ERROR; + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Limits); + GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if(!GPS_Write_Packet(fd,trapkt)) + return gps_errno; + if(!GPS_Get_Ack(fd, &trapkt, &recpkt)) + return gps_errno; + if(!GPS_Packet_Read(fd, &recpkt)) + return gps_errno; + if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) + return gps_errno; + + switch(gps_course_limits_type) { + case pD1013: + GPS_D1013_Get(limits,recpkt->data); + break; + default: + GPS_Error("A1009_Get: Unknown Course Limits protocol %d\n", + gps_course_limits_type); + return PROTOCOL_ERROR; + } + + GPS_Packet_Del(&trapkt); + GPS_Packet_Del(&recpkt); + + if (!GPS_Device_Off(fd)) + return gps_errno; + return 1; +} + + +/* @func GPS_D1013_Get ****************************************************** +** +** Convert packet D1013 to course limits structure +** +** @param [w] limits [GPS_PCourse_Limits] course limits structure +** @param [r] p [UC *] packet data +** +** @return [void] +************************************************************************/ +void GPS_D1013_Get(GPS_PCourse_Limits limits, UC *p) +{ + limits->max_courses = GPS_Util_Get_Uint(p); + p+=sizeof(uint32); + + limits->max_course_laps = GPS_Util_Get_Uint(p); + p+=sizeof(uint32); + + limits->max_course_pnt = GPS_Util_Get_Uint(p); + p+=sizeof(uint32); + + limits->max_course_trk_pnt = GPS_Util_Get_Uint(p); + p+=sizeof(uint32); +} + + /* * It's unfortunate that these aren't constant and therefore switchable, * but they really are runtime variable. Sigh. @@ -7331,3 +7378,54 @@ static UC Is_Trackpoint_Invalid(GPS_PTrack trk) return trk->no_latlon && trk->distance > 1e24 && !trk->heartrate && !trk->cadence; } + + +/* @func GPS_Prepare_Track_For_Device ********************************** +** +** Perform device-specific adjustments on a track before upload. +** +** @param [r] trk [GPS_PTrack **] track +** @param [r] n [int32 *] Number of trackpoints +************************************************************************/ +void GPS_Prepare_Track_For_Device(GPS_PTrack **trk, int32 *n) +{ + int32 i, j; + + /* D303/304 marks track segments with two consecutive invalid track + * points instead of the tnew flag. Create them unless we're at the + * beginning of a track or there are already invalid track points + * (because the track was downloaded using D303/304). This needs to be + * done here because it will change the number of track points. + */ + if (gps_trk_type == pD303 || gps_trk_type == pD304) + { + for(i=0;i<*n;++i) + { + if ((*trk)[i]->tnew && i>0 && !(*trk)[i]->ishdr && !(*trk)[i-1]->ishdr) + { + /* Create invalid points based on the data from the point + * marked with tnew and the one before it. + */ + for (j=i-1; j<=i; j++) + { + if (!Is_Trackpoint_Invalid((*trk)[j])) + { + GPS_PTrack trkpt = GPS_Track_New(); + *trkpt = *((*trk)[j]); + trkpt->no_latlon = 1; + trkpt->alt = 1e25; + trkpt->distance_populated = 0; + trkpt->heartrate = 0; + trkpt->cadence = 0xff; + *trk = xrealloc(*trk, (*n+1) * sizeof(GPS_PTrack)); + memmove(&(*trk)[i+1], &(*trk)[i], (*n-i) * sizeof(GPS_PTrack)); + (*trk)[i] = trkpt; + i++; + j++; + (*n)++; + } + } + } + } + } +} diff --git a/jeeps/gpsapp.h b/jeeps/gpsapp.h index b835cfbd5..6d1ee33cc 100644 --- a/jeeps/gpsapp.h +++ b/jeeps/gpsapp.h @@ -81,6 +81,9 @@ int32 GPS_A1008_Send(const char *port, GPS_PCourse_Point *cpt, int32 n_cpt, void GPS_D1012_Get(GPS_PCourse_Point *cpt, UC *p); void GPS_D1012_Send(UC *data, GPS_PCourse_Point cpt, int32 *len); +int32 GPS_A1009_Get(const char *port, GPS_PCourse_Limits limits); +void GPS_D1013_Get(GPS_PCourse_Limits limits, UC *p); + /* Unhandled documented protocols, as of: Garmin Device Interface Specification, May 19, 2006, Drawing Number: 001-00063-00 Rev. C A650 FlightBook Transfer Protocol @@ -95,8 +98,6 @@ A1004 Fitness User Profile Transfer Protocol Capability A1004: D1004 A1005 Workout Limits Transfer Protocol Capability A1005: D1005 -A1009 Course Limits Transfer Protocol - Capability A1009: D1013 */ /* Unimplemted and Undocumented, as listed from the following device/sw: GF305 3.70 @@ -113,6 +114,7 @@ Capability A1013: D1014 const char * Get_Pkt_Type(US p, US d0, const char **xinfo); +void GPS_Prepare_Track_For_Device(GPS_PTrack **trk, int32 *n); #endif diff --git a/jeeps/gpscom.c b/jeeps/gpscom.c index 77f68a8b1..ee80f686f 100644 --- a/jeeps/gpscom.c +++ b/jeeps/gpscom.c @@ -793,14 +793,42 @@ int32 GPS_Command_Send_Course int32 n_cpt) { gpsdevh *fd; + GPS_OCourse_Limits limits; + int32 ret; int32 ret_crs=0; int32 ret_clp=0; int32 ret_trk=0; int32 ret_cpt=0; - if(gps_course_transfer == -1) + if(gps_course_transfer == -1 || gps_course_limits_transfer == -1) return GPS_UNSUPPORTED; + /* Check course limits to make sure we're not exceeding the device's + * capacity. + */ + switch(gps_course_limits_transfer) + { + case pA1009: + ret = GPS_A1009_Get(port,&limits); + break; + default: + GPS_Error("Send_Course: Unknown course limitsprotocol"); + return PROTOCOL_ERROR; + } + + if (n_crs > limits.max_courses + || n_clp > limits.max_course_laps + || n_trk > limits.max_course_trk_pnt + || n_cpt > limits.max_course_pnt) + { + GPS_Error("Course upload would exceed device capacity:"); + GPS_Error("# of courses: %d, max: %d", n_crs, limits.max_courses); + GPS_Error("# of laps: %d, max: %d", n_clp, limits.max_course_laps); + GPS_Error("# of track points: %d, max: %d", n_trk, limits.max_course_trk_pnt); + GPS_Error("# of course points: %d, max: %d", n_cpt, limits.max_course_pnt); + return GPS_UNSUPPORTED; + } + /* Initialize device communication: * In contrast to other transfer protocols, this has to be handled here; * shutting off communication in between the different parts @@ -1165,7 +1193,7 @@ int32 GPS_Command_Send_Track_As_Course(const char *port, GPS_PTrack *trk, int32 if (trk[trk_end+1]->ishdr) break; if (trk_end==i) - trk_end=0; /* Empty track */ + continue; /* Skip empty track */ /* Create & append course */ crs = xrealloc(crs, (n_crs+1) * sizeof(GPS_PCourse)); @@ -1192,14 +1220,16 @@ int32 GPS_Command_Send_Track_As_Course(const char *port, GPS_PTrack *trk, int32 /* Append new track points */ ctk = xrealloc(ctk, (n_ctk+n_trk) * sizeof(GPS_PTrack)); - first_new_ctk = n_ctk; for (i=0;iishdr && (i>=n_trk || trk[i+1]->ishdr)) + continue; + ctk[n_ctk] = GPS_Track_New(); if (!ctk[n_ctk]) return MEMORY_ERROR; *ctk[n_ctk] = *trk[i]; - if (ctk[n_ctk]->ishdr) + if (trk[i]->ishdr) { /* Index of new track, must match the track index in associated course */ memset(ctk[n_ctk]->trk_ident, 0, sizeof(ctk[n_ctk]->trk_ident)); @@ -1219,7 +1249,7 @@ int32 GPS_Command_Send_Track_As_Course(const char *port, GPS_PTrack *trk, int32 int min_dist_idx = 0, trk_idx = 0, min_dist_trk_idx = 0; /* Find closest track point */ - for (j=first_new_ctk; jishdr) { trk_idx = strtoul(ctk[j]->trk_ident, NULL, 0); continue; diff --git a/jeeps/gpslibusb.c b/jeeps/gpslibusb.c index a816c38df..ef82454b3 100644 --- a/jeeps/gpslibusb.c +++ b/jeeps/gpslibusb.c @@ -43,8 +43,8 @@ * coalescion into packets anyway becuase of their serial background) will * compensate. */ -#define TMOUT_I 3000 /* Milliseconds to timeout intr pipe access. */ -#define TMOUT_B 3000 /* Milliseconds to timeout bulk pipe access. */ +#define TMOUT_I 5000 /* Milliseconds to timeout intr pipe access. */ +#define TMOUT_B 5000 /* Milliseconds to timeout bulk pipe access. */ typedef struct { struct usb_bus *busses;